package com.yycx.module.file.provider.oss;


import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.utils.ApiAssert;
import com.yycx.module.file.client.entity.SysFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.imaging.ImageInfo;
import org.apache.commons.imaging.Imaging;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Date;

/**
 * 文件上传
 *
 * @author flyme
 */
@Slf4j
public class FileUploadUtil {
    /**
     * 图片超过多少生成缩略图
     */
    private final static Integer FILE_SIZE = 51200;


    /**
     * 获取图片属性
     */
    public static void getImgProperty(MultipartFile file, String fileName, SysFile sysFile) {
        if (FileUploadUtil.isPicture(getExtend(fileName))) {
            try {
                ImageInfo imageInfo = Imaging.getImageInfo(file.getInputStream(), fileName);
                Integer width = imageInfo.getWidth();
                Integer height = imageInfo.getHeight();
                Integer widthDpi = imageInfo.getPhysicalHeightDpi();
                Integer heightDpi = imageInfo.getPhysicalWidthDpi();
                if(heightDpi>0){
                    sysFile.setWidthDpi(widthDpi);
                    sysFile.setHeightDpi(heightDpi);
                }
                sysFile.setWidth(width);
                sysFile.setHeight(height);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 缩放图像
     *
     * @param source 源图像文件地址
     * @param result 缩放后的图像地址
     * @param scale  缩放比例
     * @param flag   缩放选择:true 放大; false 缩小;
     */
    public static void scale(String source, String result, int scale, boolean flag) {
        try {
            // 读入文件
            BufferedImage src = ImageIO.read(new File(source));
            // 得到源图宽
            int width = src.getWidth();
            // 得到源图长
            int height = src.getHeight();
            if (flag) {
                // 放大
                width = width * scale;
                height = height * scale;
            } else {
                // 缩小
                width = width / scale;
                height = height / scale;
            }
            Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT);
            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            // 绘制缩小后的图
            g.drawImage(image, 0, 0, null);
            g.dispose();
            // 输出到文件流
            ImageIO.write(tag, "JPEG", new File(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取文件
     *
     * @param url
     * @param response
     */
    public static void view(String url, HttpServletResponse response) {

        File file = new File(url);
        FileInputStream i = null;
        OutputStream o = null;

        try {
            i = new FileInputStream(file);
            o = response.getOutputStream();

            byte[] buf = new byte[1024];
            int bytesRead;

            while ((bytesRead = i.read(buf)) > 0) {
                o.write(buf, 0, bytesRead);
                o.flush();
            }

            i.close();
            o.close();
        } catch (IOException e) {
            log.error(e.toString());
            ApiAssert.failure("读取文件出错");
        }
    }

    /**
     * 重命名
     *
     * @param url
     * @param toKey
     * @return
     */
    public static String renameFile(String url, String toKey) {

        String result = copyFile(url, toKey);
        deleteFile(url);
        return result;
    }

    /**
     * 复制文件
     *
     * @param url
     * @param toKey
     */
    public static String copyFile(String url, String toKey) {

        File file = new File(url);
        FileInputStream i = null;
        FileOutputStream o = null;
        String result = "";
        try {
            i = new FileInputStream(file);
            o = new FileOutputStream(new File(file.getParentFile() + "/" + toKey));

            byte[] buf = new byte[1024];
            int bytesRead;

            while ((bytesRead = i.read(buf)) > 0) {
                o.write(buf, 0, bytesRead);
            }

            i.close();
            o.close();
            result = file.getParentFile() + "/" + toKey;
        } catch (IOException e) {
            log.error(e.toString());
            ApiAssert.failure("复制文件出错");
        }
        return result;

    }

    public static void deleteFileByPath(String filePath) {
        try {
            cn.hutool.core.io.FileUtil.del(filePath);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    /**
     * 删除文件
     *
     * @param url
     */
    public static void deleteFile(String url) {
        File file = new File(url);
        file.delete();
    }

    public static InputStream getInputStream(MultipartFile file) {
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;
    }

    /**
     * 判断文件是否为图片文件(GIF,PNG,JPG)
     *
     * @param srcFilePath
     * @return
     */
    public static boolean isImage(File srcFilePath) {
        FileInputStream imgFile = null;
        byte[] b = new byte[10];
        int l = -1;
        try {
            imgFile = new FileInputStream(srcFilePath);
            l = imgFile.read(b);
            imgFile.close();
        } catch (Exception e) {
            return false;
        }

        if (l == 10) {
            byte b0 = b[0];
            byte b1 = b[1];
            byte b2 = b[2];
            byte b3 = b[3];
            byte b6 = b[6];
            byte b7 = b[7];
            byte b8 = b[8];
            byte b9 = b[9];

            if (b0 == (byte) 'G' && b1 == (byte) 'I' && b2 == (byte) 'F') {
                return true;
            } else if (b1 == (byte) 'P' && b2 == (byte) 'N' && b3 == (byte) 'G') {
                return true;
            } else if (b6 == (byte) 'J' && b7 == (byte) 'F' && b8 == (byte) 'I' && b9 == (byte) 'F') {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 判断文件是否为图片<br>
     */
    public static boolean isPicture(String extend) {
        // 文件名称为空的场合
        if (FlymeUtils.isEmpty(extend)) {
            // 返回不和合法
            return false;
        }
        // 声明图片后缀名数组
        String imgeArray[][] = {{"bmp", "0"}, {"dib", "1"}, {"gif", "2"}, {"jfif", "3"}, {"jpe", "4"}, {"jpeg", "5"}, {"jpg", "6"}, {"png", "7"}, {"tif", "8"}, {"tiff", "9"}, {"ico", "10"}};
        // 遍历名称数组
        for (int i = 0; i < imgeArray.length; i++) {
            // 判断单个类型文件的场合
            if (imgeArray[i][0].equals(extend.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断文件是否是视频<br>
     */
    public static boolean isVideo(String extend) {
        // 文件名称为空的场合
        if (FlymeUtils.isEmpty(extend)) {
            // 返回不和合法
            return false;
        }
        // 声明图片后缀名数组
        String imgeArray[][] = {{"mp4", "0"}, {"avi", "1"}, {"rmvb", "2"}, {"wmv", "3"}, {"mpeg", "4"}, {"mpg", "5"}, {"mov", "6"}};
        // 遍历名称数组
        for (int i = 0; i < imgeArray.length; i++) {
            // 判断单个类型文件的场合
            if (imgeArray[i][0].equals(extend.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断文件是否是音频<br>
     */
    public static boolean isMp3(String extend) {
        // 文件名称为空的场合
        if (FlymeUtils.isEmpty(extend)) {
            // 返回不和合法
            return false;
        }
        // 声明图片后缀名数组
        String imgeArray[][] = {{"mp3", "0"}, {"WAV", ""}};
        // 遍历名称数组
        for (int i = 0; i < imgeArray.length; i++) {
            // 判断单个类型文件的场合
            if (imgeArray[i][0].equals(extend.toLowerCase())) {
                return true;
            }
        }
        return false;
    }


    /**
     * 获取文件扩展名
     *
     * @param filename
     * @return
     */
    public static String getExtend(String filename) {
        return getExtend(filename, "");
    }


    /**
     * 获取文件扩展名
     *
     * @param filename
     * @return
     */
    public static String getExtend(String filename, String defExt) {
        if ((filename != null) && (filename.length() > 0)) {
            int i = filename.lastIndexOf('.');

            if ((i > 0) && (i < (filename.length() - 1))) {
                return (filename.substring(i + 1)).toLowerCase();
            }
        }
        return defExt.toLowerCase();
    }


    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    private File createFile(String path, String fileName) {
        File dir = new File(path);
        if (!dir.exists()) {
            //创建文件夹
            dir.mkdirs();
        }
        File f = new File(path + "/" + fileName);
        if (!f.getParentFile().exists()) {
            f.getParentFile().mkdirs();
        }
        ApiAssert.isFalse("文件名已存在", f.exists());
        return f;
    }

    private void mkdirs(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
    }
}
